package com.feel.modules.auth.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.feel.common.constant.DataStatus;
import com.feel.common.constant.HttpStatus;
import com.feel.common.exception.AuthException;
import com.feel.common.redis.RedisUtils;
import com.feel.common.utils.R;
import com.feel.common.utils.UUIDUtils;
import com.feel.modules.app.dao.UserDao;
import com.feel.modules.app.dto.UserCurrentDto;
import com.feel.modules.app.entity.UserEntity;
import com.feel.modules.app.entity.UserEntity;
import com.feel.modules.app.vo.RegisterVo;
import com.feel.modules.auth.service.UserService;
import com.feel.modules.security.PwdEncoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {


    @Autowired
    private PwdEncoder pwdEncoder;


    @Value("${relationship.defaultInvitationCode}")
    private String defaultInvitationCode;

    @Autowired
    private RedisUtils redisUtils;

    /**
     * 根据手机号创建用户创建用户
     *
     * @param registerVo
     * @return
     */
    @Override
    @Transactional
    public R createUserByPhone(RegisterVo registerVo, HttpHeaders httpHeaders) {
        String username = registerVo.getUsername();
        String password = registerVo.getPassword();
        //查询是否已经用微信公众号登录
        UserEntity userEntity = this.getOne(
                new LambdaQueryWrapper<UserEntity>()
                        .eq(UserEntity::getUsername, username)
        );
        if (ObjectUtil.isNotEmpty(userEntity)) {
            return R.error("手机号已注册！");
        } else {
            String parentInvitationCode = registerVo.getParentInvitationCode();

            //注册用户
            userEntity = UserEntity.builder()
                    .username(username)
                    .password(pwdEncoder.encode(password))
                    .build();
            this.save(userEntity);
            //登录 并获取token
            StpUtil.login(userEntity.getUserId());
            userEntity.setToken(StpUtil.getTokenValue());
            return R.ok(userEntity);
        }
    }


    /**
     * 生成邀请码
     *
     * @return
     */
    private String generateUuid7() {
        String invitationCode = UUIDUtils.generateUuid7();
        //查询数据库是否重复
        Long num = this.count(new QueryWrapper<UserEntity>().eq("invitation_code", invitationCode));
        if (num > 0) {
            invitationCode = generateUuid7();
        }
        return invitationCode;
    }

    /**
     * 缓存用户数据
     *
     * @param userId
     * @return
     */
//    @Override
//    public UserCurrentDto rebuildCurrent(Long userId) {
//        String key = String.format("current:%s", userId);
//        if (ObjectUtil.isNotEmpty(redisUtils.get(key, UserCurrentDto.class))) {
//            redisUtils.delete(key);
//        }
//        UserCurrentDto dto = current(userId);
//        redisUtils.set(key, dto);
//        return dto;
//    }

    /**
     * 查询当前用户
     *
     * @param userId
     * @return
     */
    private UserCurrentDto current(Long userId) {
        UserCurrentDto vo = new UserCurrentDto();
        vo.setUserEntity(baseMapper.selectById(userId));
        return vo;
    }

    /**
     * 校验用户名密码
     *
     * @param username
     * @param password
     * @return
     */
    @Override
    public UserEntity checkUser(String username, String password) {
        UserEntity user = loadUserByUsername(username);
        if (ObjectUtil.isEmpty(user)) {
            throw new AuthException(new R(HttpStatus.NOT_FOUND, "用户未注册"));
        }
        try {
//            if (DataStatus.STATUS_ENABLED != user.getStatus()) {
//                throw new AuthException(new R(HttpStatus.NOT_FOUND, "用户已被禁用"));
//            }
            boolean result = pwdEncoder.match(password, user.getPassword());
            if (result) {
                StpUtil.login(user.getUserId());
                //缓存当前用户
//                rebuildCurrent(user.getUserId());
                user.setToken(StpUtil.getTokenValue());
                return user;
            }
            throw new AuthException(new R(HttpStatus.LOGIN_ERROR, "用户名或密码错误"));
        } catch (RuntimeException e) {
            throw e;
        }
    }

    /**
     * 验证码登录校验
     *
     * @param username
     * @param verificationCode
     * @return
     */
    @Override
    public UserEntity checkUserByVerificationCode(String username, String verificationCode) {
        try {
            if (redisUtils.get(username).equals(verificationCode)) {
                UserEntity userEntity = this.loadUserByUsername(username);
                StpUtil.login(userEntity.getUserId());
                userEntity.setToken(StpUtil.getTokenValue());
                return userEntity;
            }
            throw new AuthException(new R(HttpStatus.LOGIN_ERROR));
        } catch (RuntimeException e) {
            throw e;
        }

    }

    @Override
    public UserEntity loadUserByUsername(String username) {
        return baseMapper.selectOne(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getUsername, username));
    }

    @Override
    public boolean restPassword(String userId, String oldPassword, String newPassword) {
        return false;
    }

    @Override
    public boolean restByuserName(String userName, String oldPassword, String newPassword) {
        return false;
    }


    @Override
    public String getOpenid(String code, String appid) {
        return null;
    }


    @Override
    public boolean confrimed(HttpServletRequest request) {
        return false;
    }


}
